Elemental MediaConvertを利用して動画変換を自動化する
コンニチハ、千葉です。
MediaConvertを利用して、mp4をHLSに変換するエントリーを書きました。
今回は、上記で作成したMediaConvertのジョブテンプレートを利用して、S3にファイルをputすると自動で動画変換する仕組みを作ってみます。処理イメージとしては以下です。
- S3にmp4をアップロード
- mp4ファイルが置かれたことをトリガーにLambdaを実行(mp4以外はLambdaは発火しない)
- LambdaからMediaConvertのジョブを作成する
- mp4がHLSに変換される
やってみた
作業サマリ
- S3バケット作成
- アップロード用(mp4ファイル配置)
- 動画変換用(HLSファイル配置)
- MediaConvertの設定
- Lambdaの実装
です。それではやっていきましょう。
S3バケットの作成
S3バケットを作成しましょう。アップロード用、動画変換用2つ作成します。因みに今回2つバケットを用意してますが、バケット1つでも問題ないです。
MediaConvertの設定
これを参考に、ジョブテンプレートを作成します。
Lambdaの実装
S3にmp4ファイルがアップロードされたタイミングで発火させるようにトリガーを設定します。
Lambdaで利用するIAMロールには、追加でMediaConvertのジョブをキックするためのポリシーを追加します。CreateJobに加え、PassRoleも必要でした。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "iam:PassRole", "mediaconvert:CreateJob" ], "Resource": "*" } ] }
Lambdaコードのポイントです。(修正箇所をハイライト)
- eventからアップされたbucket名、keyを取得しMediaConvertにジョブ作成時にインプットとして渡す
- MediaConverのジョブは、事前に作成したテンプレートを指定している。可変部分(入力ファイル、出力先)のみjsonで指定する。渡せるパラメータについては、手動でMediaConvertのジョブを作成したあとにjsonを確認できるので参考にする。
- endpoint_urlは、MediaConvertのアカウントから確認できるので、それを指定する
- create_jobのIAMロールは、こちらを参考に作成する
lambda_function
import json import urllib.parse import boto3 import os print('Loading function') s3 = boto3.client('s3') mediaconvert = boto3.client('mediaconvert', region_name='ap-northeast-1', endpoint_url='https://xxxxxxxx.mediaconvert.ap-northeast-1.amazonaws.com') def lambda_handler(event, context): # Get the object from the event and show its content type bucket = event['Records'][0]['s3']['bucket']['name'] key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8') inputFile = "s3://" + bucket + "/" + key outputKey = "s3://[出力するバケット]/[キー]" try: # Load job.json from disk and store as Python object: job_object with open("job.json", "r") as jsonfile: job_object = json.load(jsonfile) # Input/Output Setting job_object["OutputGroups"][0]["OutputGroupSettings"]["HlsGroupSettings"]["Destination"] = outputKey job_object["OutputGroups"][1]["OutputGroupSettings"]["FileGroupSettings"]["Destination"] = outputKey job_object["Inputs"][0]["FileInput"] = inputFile # Exec MediaConvert's job response = mediaconvert.create_job( JobTemplate='arn:aws:mediaconvert:ap-northeast-1:XXXXXXXXXXXX:jobTemplates/[ジョブテンプレート名]', Queue='arn:aws:mediaconvert:ap-northeast-1:XXXXXXXXXXXX:queues/Default', Role='arn:aws:iam::XXXXXXXXXXXX:role/[ロール名]', Settings=job_object ) except Exception as e: print(e) print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket)) raise e
job.json
{ "OutputGroups": [ { "Name": "Apple HLS", "OutputGroupSettings": { "Type": "HLS_GROUP_SETTINGS", "HlsGroupSettings": { "Destination": "" } } }, { "Name": "File Group", "OutputGroupSettings": { "Type": "FILE_GROUP_SETTINGS", "FileGroupSettings": { "Destination": "" } } } ], "Inputs": [ { "FileInput": "" } ] }
動作確認
S3へmp4をアップロードしてみます。
mp4へのアップロードをトリガーにMediaConvertのジョブが実行され、HLS形式で動画が出力されていることを確認できました。
最後に
検証時にLambdaのロールにiam:PassRoleが必要だったり、create_jobに指定するテンプレートがよくわからなかったり、はまって苦労しました。はまりつつ、いい感じに仕組みを作れたので大満足です。動画変換基盤としてご利用くださいませ。